package com.jy.api.controller.wechat;

import com.jy.api.dao.NetSchedulingTransactionDao;
import com.jy.api.dao.OpenNoticeDao;
import com.jy.api.dao.StoreDao;
import com.jy.api.domain.NetSchedulingTransaction;
import com.jy.api.domain.OpenNotice;
import com.jy.api.domain.Store;
import com.jy.api.domain.WorkShift;
import com.jy.api.enums.InstanceEnum;
import com.jy.api.service.CouponCensusService;
import com.jy.api.service.CouponInstanceService;
import com.jy.api.util.ComponentUtil;
import com.jy.api.util.WechatUtil;
import com.jy.api.wechat.service.Gzh1WxService;
import com.jy.api.wechat.service.Gzh2WxService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author Binary Wang(https://github.com/binarywang)
 */
@Slf4j
@RestController
@RequestMapping("/wechat")
public class WechatController {


    @Autowired
    private Gzh1WxService wxService;

    @Autowired
    private Gzh2WxService gzh2WxService;

    @Autowired
    ComponentUtil componentUtil;

    @Autowired
    CouponInstanceService instanceService;
    @Autowired
    private CouponCensusService censusService;
    @Autowired
    private OpenNoticeDao openNoticeDao;
    @Autowired
    private NetSchedulingTransactionDao netSchedulingTransactionDao;
    @Autowired
    private StoreDao storeDao;

    /**
     * 微信认证
     *
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/MP_verify_*")
    public String authWebGet() {
        return "Lh7F0fcfzgMrAfhN";
    }


    /**
     * 获取openid 并进行页面跳转 （优惠卷）
     *
     * @param code
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "member/share-coupon")
    public ResponseEntity getMemberCouponOpenid(@RequestParam(name = "id", defaultValue = "") String id,
                                                @RequestParam(name = "code", defaultValue = "") String code,
                                                @RequestParam(name = "state", defaultValue = "") String state) {
        try {

            log.info(" ====>>type:{} ,code:{} ,state:{}", id, code, state);
            MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
            if (StringUtils.isBlank(code) && StringUtils.isBlank(state)) {
                String url = wxService.getOAuth2Service().buildAuthorizationUrl(componentUtil.getMemberCoupon(), "snsapi_base", id);
                log.info("wxServiceAppId{},wxServiceSecret{}", wxService.getWxMpConfigStorage().getAppId(), wxService.getWxMpConfigStorage().getSecret());
                multiValueMap.add("Location", url);
                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            } else {
                //获取的是店铺宝公众号的openID
                WxOAuth2AccessToken oAuth2AccessToken = wxService.getOAuth2Service().getAccessToken(code);
                log.info(" oAuth2AccessToken info :{}", oAuth2AccessToken);
                InstanceEnum instanceEnum = instanceService.checkMemberCouponAuth(oAuth2AccessToken.getOpenId(), state);
                multiValueMap.add("Location", WechatUtil.COUPON_INDEX.replace("OPENID", oAuth2AccessToken.getOpenId())
                        .replace("TYPE", instanceEnum.toString()).replace("ID", state));
                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            }
        } catch (Exception ex) {
            log.error("openId is error=>code:{}", code, ex);
            return new ResponseEntity(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 获取openid 并进行页面跳转 （店员宝公众号）
     *
     * @param code
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "member/openid")
    public ResponseEntity getMemberopenid(@RequestParam(name = "type", defaultValue = "") String type,
                                          @RequestParam(name = "code", defaultValue = "") String code,
                                          @RequestParam(name = "state", defaultValue = "") String state,
                                          @RequestParam(name = "storeId", defaultValue = "") String storeId, @RequestParam(value = "tableNo", required = false) String tableNo) {
        try {
            log.info(" ====>>type:{} ,code:{} ,state:{}", type, code, state);
            MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
            log.info("wxServiceAppId{},wxServiceSecret{},wxServiceConfig{}", wxService.getWxMpConfigStorage().getAppId(),wxService.getWxMpConfigStorage().getSecret(),wxService.getWxMpConfigStorage());
            if (StringUtils.isBlank(code) && StringUtils.isBlank(state)) {
                String url;
                //如果storeId 为空 表示为微信点单
                if (StringUtils.equals(type, "WECHAT-ORDER")) {
                    type = storeId;
                }
                if (StringUtils.isNotBlank(tableNo) && StringUtils.isNotBlank(tableNo)) {
                    String s = URLEncoder.encode(tableNo,"UTF-8");
                    url = wxService.getOAuth2Service().buildAuthorizationUrl(componentUtil.getMemberTableNoCallback(),"snsapi_base", type).replace("TABLENO",s);
                } else {
                    url = wxService.getOAuth2Service().buildAuthorizationUrl(componentUtil.getMemberCallback(), "snsapi_base", type);
                }
                log.info("call bake  url :{}", url);
                multiValueMap.add("Location", url);
                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            } else {
                //获取的是店铺宝公众号的openID
                WxOAuth2AccessToken oAuth2AccessToken = wxService.getOAuth2Service().getAccessToken(code);
                log.info(" oAuth2AccessToken info :{}", oAuth2AccessToken);
                String url = "";
                if (StringUtils.equals("KABAO", state)) {
                    url = WechatUtil.HXBS_COUPON_URL;
                } else if (StringUtils.equals("ORDER", state)) {
                    url = WechatUtil.HXBS_ORDER_URL;
                } else if (StringUtils.equals("MY", state)) {
                    url = WechatUtil.HXBS_MY_URL;
                } else if (state.indexOf("WEB") != -1) {
                    String orderId = state.split("WEB")[1];
                    url = WechatUtil.WEB_LOGIN_URL.replace("ORDER_ID", orderId);
                } else if (state.indexOf("PAY") != -1) {
                    String orderId = state.split("PAY")[1];
                    url = WechatUtil.WEB_MEMBER_PAY_URL.replace("ORDER_ID", orderId);
                } else {
                    String s = URLEncoder.encode(tableNo,"UTF-8");
                    url = WechatUtil.WEIXIN_ORDER_URL.replace("STORE_ID", state).replace("TABLE_NO",s);
                }
                log.info("call bake  url 1 :{}", url);
                multiValueMap.add("Location", url.replace("OPENID", oAuth2AccessToken.getOpenId()));
                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            }
        } catch (Exception ex) {
            log.error("openId is error=>code:{}", code, ex);
            return new ResponseEntity(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }
    @RequestMapping(method = RequestMethod.GET, value = "/member/net")
    public ResponseEntity memberNetSchedul(@RequestParam(name = "id", defaultValue = "") int id) {
        try {
            Map<String, String> map = new HashMap<>();
            map.put("id", id+"");
            map.put("line", "line");
            String scene_str = "=" + JSONObject.fromObject(map);
            WxMpQrCodeTicket wxMpQrCodeTicket = wxService.getQrcodeService().
                    qrCodeCreateLastTicket(scene_str);
            return new ResponseEntity(wxMpQrCodeTicket.getUrl(), HttpStatus.OK);
        } catch (WxErrorException e) {
            e.printStackTrace();
            return new ResponseEntity("排单码获取失败", HttpStatus.BAD_REQUEST);
        }
    }
    /**
     * 获取openid 并进行页面跳转 （店员宝公众号）
     *
     * @param code
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/openid")
    public ResponseEntity openid(@RequestParam(name = "type", defaultValue = "CLERK") String type,@RequestParam(value = "name",defaultValue = "")String name,
                                 @RequestParam(name = "code", defaultValue = "") String code,
                                 @RequestParam(name = "state", defaultValue = "") String state, @RequestParam(value = "storeId", required = false) String storeId) {
        try {

            log.info(" ====>>type:{} ,code:{} ,state:{}", type, code, state);
            MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
            log.info("wxServiceAppId{},wxServiceSecret{},wxServiceConfig{}", wxService.getWxMpConfigStorage().getAppId(), wxService.getWxMpConfigStorage().getSecret(), wxService.getWxMpConfigStorage());
            if (StringUtils.isBlank(code)) {
                String url = "";
                if (storeId != null) {
                    url = gzh2WxService.getOAuth2Service().buildAuthorizationUrl(String.format("https://prod-api.huoxingy.com/wechat/openid?storeId=STOREID&name=%s",name), "snsapi_base", type);
                    multiValueMap.add("Location", url.replace("STOREID", storeId));
                } else {
                    url = gzh2WxService.getOAuth2Service().buildAuthorizationUrl(String.format("https://prod-api.huoxingy.com/wechat/openid?name=%s",name), "snsapi_base", type);
                    multiValueMap.add("Location", url);
                }
                log.info("call bake  url :{}", url);

                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            } else {
                //获取的是店铺宝公众号的openID
                WxOAuth2AccessToken oAuth2AccessToken = gzh2WxService.getOAuth2Service().getAccessToken(code);
                log.info(" get openid oAuth2AccessToken:{}", oAuth2AccessToken);
                String url = "";
                if (StringUtils.equals("CLERK", state)) {
                    url = WechatUtil.CLERK_URL;
                } else if (StringUtils.equals("ADMIN", state)) {
                    url = WechatUtil.ADMIN_URL;
                } else if (StringUtils.equals("OPEN", state)) {
                    url = WechatUtil.OPEN_URL;
                    OpenNotice openNotice = openNoticeDao.findByOpenIdAndStoreId(oAuth2AccessToken.getOpenId(), storeId);
                    if (null == openNotice && !StringUtils.isEmpty(storeId)) {
                        final WxMpUser wxMpUser = gzh2WxService.getUserService().userInfo(oAuth2AccessToken.getOpenId());
                        OpenNotice open = new OpenNotice(name, wxMpUser.getHeadImgUrl(), wxMpUser.getOpenId(), storeId);
                        openNoticeDao.save(open);
                    }
                }
                multiValueMap.add("Location", url.replace("OPENID", oAuth2AccessToken.getOpenId()));
                return new ResponseEntity(multiValueMap, HttpStatus.MOVED_PERMANENTLY);
            }
        } catch (Exception ex) {
            log.error("openId is error=>code:{}", code, ex);
            return new ResponseEntity(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }


    /**
     * 获取分享请求参数
     *
     * @param url
     * @return
     * @throws WxErrorException
     */
    @RequestMapping(value = "/signature", method = RequestMethod.GET)
    public ResponseEntity getSignature(@RequestParam(value = "url") String url) throws WxErrorException {
        String url1 = "";
        url = url.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
        try {
            url1 = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        WxJsapiSignature wxJsapiSignature = wxService.createJsapiSignature(url1);
        return ResponseEntity.ok(wxJsapiSignature);
    }


    /**
     * <pre>
     * 自定义菜单创建接口
     * 详情请见：https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN
     * 如果要创建个性化菜单，请设置matchrule属性
     * 详情请见：https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN
     * </pre>
     *
     * @param menu
     * @return 如果是个性化菜单，则返回menuid，否则返回null
     */
    @PostMapping("/create")
    public String menuCreate(@RequestBody WxMenu menu) throws WxErrorException {
        return this.wxService.getMenuService().menuCreate(menu);
    }


    @GetMapping("add-count")
    public ResponseEntity addCount(@RequestParam("id") String id, @RequestParam("type") String type) {
        censusService.clickAndShareCount(id, type);
        return ResponseEntity.ok().build();
    }


    @GetMapping("/menuAuto")
    public String menuAuto() throws WxErrorException {
        WxMenu menu = new WxMenu();
        List<WxMenuButton> buttons = new ArrayList<>();
        WxMenuButton button1 = new WxMenuButton();
        button1.setType("view");
        button1.setName("个人资料");
        button1.setUrl(componentUtil.getMemberCallback() + "?type=MY");
        buttons.add(button1);
        WxMenuButton button2 = new WxMenuButton();
        button2.setType("view");
        button2.setName("我的卡包");
        button2.setUrl(componentUtil.getMemberCallback() + "?type=KABAO");
        buttons.add(button2);
        WxMenuButton button3 = new WxMenuButton();
        button3.setType("view");
        button3.setName("消费记录");
        button3.setUrl(componentUtil.getMemberCallback() + "?type=ORDER");
        buttons.add(button3);
        menu.setButtons(buttons);
        return this.gzh2WxService.getMenuService().menuCreate(menu);
    }


}
